package org.sl.flvplayer.data {
	import org.sl.flvplayer.controls.PlayerLogic;
	import org.sl.flvplayer.flyweights.FWPlayerCommand;

	import flash.display.Sprite;
	import flash.events.Event;

	/**
	 * Processes the information provided by the xml object as an VideoItem and provides means of playback behavior for the playlist.</br>
	 * The first video is only attached to stage when the previewimage is loaded!
	 * 
	 * @package org.sl.flvplayer.data
	 * @author Dan
	 * @version 
	 * @see org.sl.flvplayer.data.InitData
	 * @see org.sl.flvplayer.controls.PlayerLogic
	 * @see org.sl.flvplayer.data.VideoItem
	 */ 
	public class Playlist extends Sprite {
		
		private static var instance : Playlist;
		
		private var videoList : Array = new Array();
		private var lastItem : VideoItem;
		private var cursor : Number = 0;

		/**
		 * Ensures that there is only one instance of the class by using the singleton pattern.
		 *
		 * @return instance of the <code>Playlist</code> class 
		 */
		public static function getInstance() : Playlist {
			if(!instance) instance = new Playlist();
			return instance;	
		}

		/**
		 * Processes each videoNode of the xml playlist in a  seperate VideoItem and pushes it in the videoList array.
		 *
		 * @param p_playlist videoplaylist xml object
		 */
		public function init(p_playlist : XML) : void {
		// handles the videonodes of the playlist xml
			for each (var videoNode : XML in p_playlist.video) {
				lastItem = new VideoItem(videoNode);
				videoList.push(lastItem);
			}		
			this.addEventListener(Event.ENTER_FRAME, onEnterFrame);
		}

		/**
		 * Processes the p_videoSource xml which was created from the flashVars in an VideoItem and pushes it in the videoList array.
		 *
		 * @param p_videoSource xml object createt from the parsed flashVars
		 */
		public function addVideoSource(p_videoSource : XML) : void {
			lastItem = new VideoItem(p_videoSource);
			videoList.push(lastItem);
			this.addEventListener(Event.ENTER_FRAME, onEnterFrame);
		}

		/**
		 * Initializes the current video when the previewimage is loaded and starts the playback if the autoPlay parameter is set to true.</br>
		 * When autoplay is on the PAUSE command is executed.
		 * 	
		 * @param p_event
		 */
		private function onEnterFrame(p_event : Event) : void {	
			// checks whether the isLoaded method returns true
			if (VideoItem(videoList[cursor]).isLoaded()) {
				this.removeEventListener(Event.ENTER_FRAME, onEnterFrame);	
				PlayerLogic.getInstance().command(new FWPlayerCommand(FWPlayerCommand.SOURCE, this, [videoList[cursor]]));
				PlayerLogic.getInstance().command(new FWPlayerCommand(FWPlayerCommand.RENDER, this));
				if(Config.getInstance().autoPlay) {
					PlayerLogic.getInstance().command(new FWPlayerCommand(FWPlayerCommand.PAUSE, this)); 
				}	
			}
		}

		/**
		 * Processes the next video in the videoList array.</br>
		 * When the last video is played the STOP command is executed
		 * 
		 * @return returns <code>true</code> if there is a new video in the <code>videoList</code> or returns <code>false</code> if there is no new video and executes a <code>STOP</code> command
		 */
		public function playNext() : Boolean {
			if (++cursor < videoList.length) {
				this.addEventListener(Event.ENTER_FRAME, onEnterFrame);	
				return true;
			}
			PlayerLogic.getInstance().command(new FWPlayerCommand(FWPlayerCommand.STOP, this));
			return false;
		}		
	}
}
